import os
import json
import re
import random
from datetime import datetime

def refresh_layout_button ( ) :

    global xrn_main_window_global
    render_layout( xrn_main_window_global.jlayout_str )


def store_layout_settings ( ) :

    global xrn_main_window_global
    slayout_local = xrn_main_window_global.jlayout_str

    obj = get_from_layout ( slayout_local, "store_layout_setting_path" )
    file_path = obj["fields"][2]["display"] 

    # remove display of visibility

    id_tree = build_id_trees_layout(slayout_local, "") 
    id_tree_rows = id_tree.split("\n")

    for id_row in id_tree_rows :
        lastid = id_row.split(" ")[-1]
        obj = get_from_layout ( slayout_local, lastid )
        if obj["fields"][2]["type"] == "string" :
            if obj["fields"][2]["visibility"] == "closed" :
                obj["fields"][2]["display"] = ""
                slayout_local = set_to_layout( slayout_local, obj )

    obj = get_from_layout ( slayout_local, "store_layout_setting_path" )

    # Add an item to the "items" list of the "archive" field

    data = json.loads(slayout_local)
    try :
        with open(file_path, 'w') as f:
            json.dump(data, f, indent=4)
            open_text_popup( "layout stored" )
    except IOError as error:
        open_text_popup( "layout not stored" )


def load_layout_settings ( ) :

    global xrn_main_window_global
    slayout_local = xrn_main_window_global.jlayout_str

    local_footprint_tmp = build_id_trees_layout(slayout_local, "") 
    lines = [line.strip() for line in local_footprint_tmp.strip().split('\n') if line.strip()]
    filtered_lines = [line for line in lines if "layout_control_panel" not in line.split()]
    local_footprint = '\n'.join(filtered_lines) + '\n'
    local_footprint_lastids = [] 
    for row in local_footprint.split("\n") :
        local_footprint_lastids.append( row.split(" ")[-1] )

    obj = get_from_layout ( slayout_local, "load_layout_setting_path" )
    file_path = obj["fields"][2]["display"] 

    if os.access(file_path, os.R_OK) :
        try:
            with open(file_path, 'r') as f:
                data = json.load(f)
                data_str = json.dumps(data)
                remote_footprint_tmp = build_id_trees_layout(data_str, "") 
                lines = [line.strip() for line in remote_footprint_tmp.strip().split('\n') if line.strip()]
                filtered_lines = [line for line in lines if "layout_control_panel" not in line.split()]
                remote_footprint = '\n'.join(filtered_lines) + '\n'
                remote_footprint_lastids = [] 
                for row in remote_footprint.split("\n") :
                    remote_footprint_lastids.append( row.split(" ")[-1] )

                error = 0
                for remote_id in remote_footprint_lastids :
                    if remote_id not in local_footprint_lastids :
                        obj = get_from_layout ( data_str, remote_id )
                        if "function" in obj["fields"][2] :
                            if "function" != "" :
                                error = 1

                if error == 0 :
                    obj = get_from_layout ( data_str, "load_layout_setting_path" )
                    obj["fields"][2]["display"] = file_path
                    data_str = set_to_layout( data_str, obj )
                    render_layout(  data_str )
                    open_text_popup( "layout loaded" )
                else :
                    open_text_popup( "layout not loaded, non matching layout" )

        except json.JSONDecodeError as e:
            open_text_popup( f"Invalid JSON: {e}" )

    else :
        open_text_popup( "layout can not be accessed" )

def search_layout_settings ( ) :

    global xrn_main_window_global
    slayout_local = xrn_main_window_global.jlayout_str
    # build popup
    obj = get_from_layout ( slayout_local, "search_settings_in_layout" )
    popup_layout_output  = general_control_panel_get_initial_popup( obj["fields"][0]["display"], "response"  )

    obj = get_from_layout ( slayout_local, "search_settings_in_layout" )
    string_to_search = obj["fields"][2]["display"].lower()
    search_display = obj["fields"][0]["display"]

    data = json.loads(slayout_local)

    id_tree = build_id_trees_layout(slayout_local, "") 
    id_tree_rows = id_tree.split("\n")

    # search
    found_match = []
    matches = []

    for id_row in id_tree_rows :
        found = 0
        if not ( "layout_control_panel" in id_row ):
            lastid = id_row.split(" ")[-1]
            obj = get_from_layout ( slayout_local, lastid )

            if string_to_search in obj["fields"][0]["display"].lower() :
                found_match = found_match + [1]
                matches = matches + [obj["fields"][0]["display"]]
                found = 1
            else :
                if ( obj["fields"][2]["type"] == "combobox" ):
                    for item in obj["fields"][2]["items"]:
                        if string_to_search in item["display"].lower() :
                            found_match = found_match + [1]
                            matches = matches + [item["display"]]
                            found = 1

                elif ( obj["fields"][2]["type"] == "archive" ):
                    for item in obj["fields"][2]["items"]:

                        if string_to_search in item["display"].lower() :
                            found_match = found_match + [1]
                            matches = matches + [item["display"]]
                            found = 1

                        elif string_to_search in item["data"].lower() :
                            found_match = found_match + [1]
                            matches = matches + [item["display"]]
                            found = 1

                else :
                    if string_to_search in obj["fields"][2]["display"].lower() :
                        found_match = found_match + [1]
                        matches = matches + [obj["fields"][2]["display"]]
                        found = 1
        if found == 0 :
            found_match = found_match + [0]
            matches = matches + [""]

    display_string = ""
    row_index = 0
    first_display_row = 0
    found_at_least_one_match = 0

    for id_row in id_tree_rows :

        if found_match[row_index] == 1 :

            found_at_least_one_match = 1
            if first_display_row == 0 :
                first_display_row = 1
            else :
                display_string = display_string + "\n"

            first_element = 0
            for element in id_row.split(" ")[:-1] :
                obj = get_from_layout ( slayout_local, element )
                if first_element == 0 :
                    first_element = 1
                    display_string = display_string + obj["display"]
                else :
                    display_string = display_string + " -> " + obj["display"]

            display_string = display_string + " -> " + matches[row_index]

        row_index = row_index + 1

    # Initialize the "fields" key as a list and append dictionaries
    popup_layout_output[0]["rows"][1]["fields"] = []
    if string_to_search == "" :
        popup_layout_output[0]["rows"][1]["fields"].append({"type": "textbox", "display": "no string entered" })
    else :
        popup_layout_output[0]["rows"][1]["fields"].append({"type": "textbox", "display": "search: " + string_to_search })
    popup_layout_output[0]["rows"][1]["fields"].append({"type": "void"})

    if found_at_least_one_match == 1 :

        popup_layout_output[0]["rows"][1]["fields"].append({"type": "archive", "selection": "match 0", "items": []})

        rows = display_string.split("\n")
        index = 0
        for row in rows :

            fields = row.split("->")
            initial_field = 0
            display_string_show = ""
            for field in fields :
                if ( initial_field != 0 ):
                    display_string_show = display_string_show + "    "
                display_string_show = display_string_show + field
                initial_field = 1
                display_string_show = display_string_show + "\n"
            popup_layout_output[0]["rows"][1]["fields"][2]["items"].append({"display": "match " + str(index), "data": display_string_show })
            index = index + 1

        popup_layout_output[0]["rows"].append({})
        popup_layout_output[0]["rows"][2]["permission"] = "read_write"
        popup_layout_output[0]["rows"][2]["id"] = "search_layout_settings_" + str(random.randint(0, 10000))
        popup_layout_output[0]["rows"][2]["type"] = "row"
        popup_layout_output[0]["rows"][2]["fields"] = []
        popup_layout_output[0]["rows"][2]["fields"].append({"type": "textbox", "display": "result" })
        popup_layout_output[0]["rows"][2]["fields"].append({"type": "void"})
        popup_layout_output[0]["rows"][2]["fields"].append({"type": "archive", "selection": "result", "items": []})
        popup_layout_output[0]["rows"][2]["fields"][2]["items"].append({"display": "result", "data": "pass" })

    else :
        popup_layout_output[0]["rows"][1]["fields"].append({"type": "archive", "selection": "pattern not found", "items": []})
        popup_layout_output[0]["rows"][1]["fields"][2]["items"].append({"display": "pattern not found", "data": "pattern not found" })

        popup_layout_output[0]["rows"].append({})
        popup_layout_output[0]["rows"][2]["permission"] = "read_write"
        popup_layout_output[0]["rows"][2]["id"] = "search_layout_settings_" + str(random.randint(0, 10000))
        popup_layout_output[0]["rows"][2]["type"] = "row"
        popup_layout_output[0]["rows"][2]["fields"] = []
        popup_layout_output[0]["rows"][2]["fields"].append({"type": "textbox", "display": "result" })
        popup_layout_output[0]["rows"][2]["fields"].append({"type": "void"})
        popup_layout_output[0]["rows"][2]["fields"].append({"type": "archive", "selection": "result", "items": []})
        popup_layout_output[0]["rows"][2]["fields"][2]["items"].append({"display": "result", "data": "fail" })

    popup_layout_output_srt = json.dumps( popup_layout_output )
    return popup_layout_output_srt 

def expand_all_layout_setting_button():
    global xrn_main_window_global
    slayout_local = xrn_main_window_global.jlayout_str
    id_tree = build_id_trees_layout(slayout_local, "") 
    rows = id_tree.split("\n")
    for row in rows :
        elements_id = row.split(" ")
        for element_id in elements_id :
            obj = get_from_layout ( slayout_local, element_id )
            if obj["type"] == "rows" : 
                obj["expand"] = "on"
                slayout_local = set_to_layout( slayout_local, obj )
    render_layout(  slayout_local )


def collapse_all_layout_setting_button():
    global xrn_main_window_global
    slayout_local = xrn_main_window_global.jlayout_str
    id_tree = build_id_trees_layout(slayout_local, "") 
    rows = id_tree.split("\n")
    for row in rows :
        elements_id = row.split(" ")
        for element_id in elements_id :
            obj = get_from_layout ( slayout_local, element_id )
            if obj["type"] == "rows" : 
                if  (obj["id"] == "layout_control_panel") : 
                    obj["expand"] = "on"
                    slayout_local = set_to_layout( slayout_local, obj )
                else :
                    obj["expand"] = "off"
                    slayout_local = set_to_layout( slayout_local, obj )
    render_layout(  slayout_local )

def load_log_setting_button():
    global xrn_main_window_global
    slayout_local = xrn_main_window_global.jlayout_str

    file_path = get_from_layout( slayout_local, "path_archive_to_load" )["fields"][2]["display"]
    file_content = ""
    with open(file_path, 'r') as f:
        file_content = f.read()

    if is_archive_only( file_content ) == 1 :
        obj_lst = json.loads( file_content )
        dst_obj = get_from_layout( slayout_local, "general_archive_panel_id" )
        dst_obj["expand"] = "on" 
        dst_obj["rows"] = []
        for obj in obj_lst :
            dst_obj["rows"].append(obj)

        slayout_local = set_to_layout( slayout_local, dst_obj )

        render_layout(  slayout_local )

def reset_log_setting_button ():

    global xrn_main_window_global
    slayout_local = xrn_main_window_global.jlayout_str

    dst_obj = get_from_layout( slayout_local, "general_archive_panel_id" )
    dst_obj["rows"] = [] 
    dst_obj["expand"] = "off" 
    slayout_local = set_to_layout( slayout_local, dst_obj )
    render_layout(  slayout_local )

def merge_archives_button ():
    global xrn_main_window_global
    slayout_local = xrn_main_window_global.jlayout_str
    first_archive_path = get_from_layout( slayout_local, "first_source_archive_file" )["fields"][2]["display"]
    second_archive_path = get_from_layout( slayout_local, "second_source_archive_file" )["fields"][2]["display"]
    destination_archive_path = get_from_layout( slayout_local, "destination_archive_file" )["fields"][2]["display"]

    try :
        first_archive_path_content = ""
        with open( first_archive_path , 'r') as f:
            first_archive_path_content  = f.read()

        second_archive_path_content = ""
        with open( second_archive_path , 'r') as f:
            second_archive_path_content  = f.read()

        if (( is_archive_only( first_archive_path_content ) + is_archive_only( second_archive_path_content ) ) == 2 ) :
            first_archive_obj = json.loads(first_archive_path_content)
            second_archive_obj = json.loads(second_archive_path_content)
            destination_obj = []
            index = 0

            for obj in first_archive_obj :
                obj["expand"] = "off"
                obj["id"] = "merge_archives_button_" + str(random.randint(0,100000)) + "_" + str(index)
                destination_obj.append(obj) 
                index = index + 1

            for obj in second_archive_obj :
                obj["id"] = "merge_archives_button_" + str(random.randint(0,100000)) + "_" + str(index)
                obj["expand"] = "off"
                destination_obj.append(obj) 
                index = index + 1

            destination_archive_content = json.dumps(destination_obj)

            with open( destination_archive_path , 'w') as f:
                f.write( destination_archive_content )
                open_text_popup( "file merged" )
    except :
        open_text_popup( "files not merged" )

def layout_control_panel_combobox_button ():
    global xrn_main_window_global
    slayout_local = xrn_main_window_global.jlayout_str

    selection = get_from_layout ( slayout_local, "layout_control_panel_combobox" )["fields"][2]["selection"]

    obj = get_from_layout ( slayout_local, "store_layout_setting_path" )
    obj["permission"] = "read_only" 
    slayout_local = set_to_layout( slayout_local, obj )

    obj = get_from_layout ( slayout_local, "store_layout_setting_button" )
    obj["permission"] = "read_only" 
    slayout_local = set_to_layout( slayout_local, obj )

    obj = get_from_layout ( slayout_local, "load_layout_setting_path" )
    obj["permission"] = "read_only" 
    slayout_local = set_to_layout( slayout_local, obj )

    obj = get_from_layout ( slayout_local, "load_layout_setting_button" )
    obj["permission"] = "read_only" 
    slayout_local = set_to_layout( slayout_local, obj )

    obj = get_from_layout ( slayout_local, "first_source_archive_file" )
    obj["permission"] = "read_only" 
    slayout_local = set_to_layout( slayout_local, obj )

    obj = get_from_layout ( slayout_local, "second_source_archive_file" )
    obj["permission"] = "read_only" 
    slayout_local = set_to_layout( slayout_local, obj )

    obj = get_from_layout ( slayout_local, "destination_archive_file" )
    obj["permission"] = "read_only" 
    slayout_local = set_to_layout( slayout_local, obj )

    obj = get_from_layout ( slayout_local, "merge_archives_id" )
    obj["permission"] = "read_only" 
    slayout_local = set_to_layout( slayout_local, obj )

    obj = get_from_layout ( slayout_local, "path_archive_to_load" )
    obj["permission"] = "read_only" 
    slayout_local = set_to_layout( slayout_local, obj )

    obj = get_from_layout ( slayout_local, "load_log_setting_id" )
    obj["permission"] = "read_only" 
    slayout_local = set_to_layout( slayout_local, obj )

    obj = get_from_layout ( slayout_local, "reset_log_setting_id" )
    obj["permission"] = "read_only" 
    slayout_local = set_to_layout( slayout_local, obj )

    if selection == "store layout" :
        obj = get_from_layout ( slayout_local, "store_layout_setting_path" )
        obj["permission"] = "read_write" 
        slayout_local = set_to_layout( slayout_local, obj )

        obj = get_from_layout ( slayout_local, "store_layout_setting_button" )
        obj["permission"] = "read_write" 
        slayout_local = set_to_layout( slayout_local, obj )

    elif selection == "load layout" :
        obj = get_from_layout ( slayout_local, "load_layout_setting_path" )
        obj["permission"] = "read_write" 
        slayout_local = set_to_layout( slayout_local, obj )

        obj = get_from_layout ( slayout_local, "load_layout_setting_button" )
        obj["permission"] = "read_write" 
        slayout_local = set_to_layout( slayout_local, obj )


    elif selection == "merge archive" :
         obj = get_from_layout ( slayout_local, "first_source_archive_file" )
         obj["permission"] = "read_write" 
         slayout_local = set_to_layout( slayout_local, obj )

         obj = get_from_layout ( slayout_local, "second_source_archive_file" )
         obj["permission"] = "read_write" 
         slayout_local = set_to_layout( slayout_local, obj )

         obj = get_from_layout ( slayout_local, "destination_archive_file" )
         obj["permission"] = "read_write" 
         slayout_local = set_to_layout( slayout_local, obj )

         obj = get_from_layout ( slayout_local, "merge_archives_id" )
         obj["permission"] = "read_write" 
         slayout_local = set_to_layout( slayout_local, obj )

    elif selection == "view archive" :

        obj = get_from_layout ( slayout_local, "path_archive_to_load" )
        obj["permission"] = "read_write" 
        slayout_local = set_to_layout( slayout_local, obj )

        obj = get_from_layout ( slayout_local, "load_log_setting_id" )
        obj["permission"] = "read_write" 
        slayout_local = set_to_layout( slayout_local, obj )

        obj = get_from_layout ( slayout_local, "reset_log_setting_id" )
        obj["permission"] = "read_write" 
        slayout_local = set_to_layout( slayout_local, obj )

    render_layout( slayout_local )

